package tsou.com.simple.realmtest;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

import io.realm.Realm;
import io.realm.RealmAsyncTask;
import io.realm.RealmList;
import tsou.com.simple.realmtest.adapter.MyAdapter;
import tsou.com.simple.realmtest.bean.Men;
import tsou.com.simple.realmtest.bean.MorePerson;
import tsou.com.simple.realmtest.bean.Person;
import tsou.com.simple.realmtest.bean.Stock;
import tsou.com.simple.realmtest.bean.Student;
import tsou.com.simple.realmtest.bean.User;
import tsou.com.simple.realmtest.utils.UIUtils;

public class AddActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {

    private ListView mListview;
    private List<String> titles = new ArrayList<>();
    private Realm mRealm;
    private SimpleDateFormat simpleDateFormat;
    private RealmAsyncTask realmAsyncTask;

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (realmAsyncTask != null && !realmAsyncTask.isCancelled()) {
            realmAsyncTask.cancel();
        }
        if (mRealm != null && !mRealm.isClosed()) {
            mRealm.close();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add);
        mRealm = UIUtils.getRealmInstance();
        simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        initData();
        initView();
        initListener();
    }

    private void initData() {
        //***********************同步操作*********************************
        //注意：如果在UI线程中插入过多的数据，可能会导致主线程拥塞。
        titles.add("同步操作：使用executeTransaction方法插入数据");
        titles.add("同步操作：使用copyToRealmOrUpdate方法插入数据");
        titles.add("同步操作：使用copyToRealm方法插入数据");
        titles.add("同步操作：增加一对一表，Person包含Men(以executeTransaction为例)");
        titles.add("同步操作：增加一对一表，Person包含一个Men(以copyToRealm为例)");
        titles.add("同步操作：增加一对多表，Person包含多个Men(以executeTransaction为例)");
        titles.add("同步操作：增加一对多表，Person包含多个Men(以copyToRealm为例)");
        titles.add("同步操作：beginTransaction和commitTransaction方法插入数据");
        //***********************异步操作*********************************
        titles.add("异步操作：使用executeTransactionAsync直接插入数据");
        titles.add("异步操作：使用executeTransactionAsync并且进行监听");
        //***********************将Json字符串转化为对象*****************
        titles.add("将Json字符串转化为对象(使用Json字符串插入数据)");
    }

    private void initView() {
        mListview = (ListView) findViewById(R.id.listview);

        mListview.setAdapter(new MyAdapter(this, titles));
    }

    private void initListener() {
        mListview.setOnItemClickListener(this);
    }

    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
        switch (position) {
            default:
                break;
            case 0://同步操作：使用executeTransaction方法插入数据
                mRealm.executeTransaction(new Realm.Transaction() {
                    @Override
                    public void execute(Realm realm) {
                        Student student = realm.createObject(Student.class);
                        student.setName("使用executeTransaction方法插入数据");
                        student.setNum(new Random().nextInt(20));
                    }
                });
                break;
            case 1://同步操作：使用copyToRealmOrUpdate方法插入数据
                /**
                 * 当Model中存在主键的时候，推荐使用copyToRealmOrUpdate方法插入数据。
                 * 如果对象存在，就更新该对象；反之，它会创建一个新的对象。
                 */
                final User user = new User();
                user.setId(2);
                user.setName("使用copyToRealmOrUpdate方法插入数据");
                user.setAge(new Random().nextInt(20));
                user.setSex("同步");
                mRealm.executeTransaction(new Realm.Transaction() {
                    @Override
                    public void execute(Realm realm) {
                        realm.copyToRealmOrUpdate(user);
                    }
                });
                break;
            case 2://同步操作：使用copyToRealm方法插入数据
                /**
                 *若该Model没有主键，使用copyToRealm方法，否则将抛出异常。
                 */
                final Student student = new Student();
                student.setName("使用copyToRealm方法插入数据");
                student.setNum(new Random().nextInt(20));
                mRealm.executeTransaction(new Realm.Transaction() {
                    @Override
                    public void execute(Realm realm) {
                        realm.copyToRealm(student);
                    }
                });
                break;
            case 3://同步操作：增加一对一表，Person包含Men(以executeTransaction为例)
                //以executeTransaction为例
                mRealm.executeTransaction(new Realm.Transaction() {
                    @Override
                    public void execute(Realm realm) {
                        Person person = realm.createObject(Person.class);
                        person.setCity("杭州");
                        person.setProject("android");

                        Men men = realm.createObject(Men.class);
                        men.setName("huangxiaoguo");
                        men.setAge(25);

                        person.setMen(men);

                    }
                });
                break;

            case 4://同步操作：增加一对一表，Person包含Men(以copyToRealm为例)
                final Person person1 = new Person();
                person1.setCity("杭州");
                person1.setProject("android");
                Men men1 = new Men();
                men1.setName("huangxiaoguo");
                men1.setAge(new Random().nextInt(100));
                person1.setMen(men1);
                mRealm.executeTransaction(new Realm.Transaction() {
                    @Override
                    public void execute(Realm realm) {
                        //如果使用copyToRealmOrUpdate，Person需要主键
                        realm.copyToRealm(person1);
                    }
                });
                break;
            case 5://同步操作：增加一对多表，Person包含多个Men(以executeTransaction为例)
                mRealm.executeTransaction(new Realm.Transaction() {
                    @Override
                    public void execute(Realm realm) {
                        MorePerson morePerson = realm.createObject(MorePerson.class);
                        morePerson.setCity("杭州");
                        morePerson.setProject("开发工程师");
                        morePerson.setTime(simpleDateFormat.format(new Date()));
                        for (int i = 0; i < 3; i++) {
                            Men men = realm.createObject(Men.class);
                            men.setName("huangxiaoguo" + i);
                            men.setAge(new Random().nextInt(100));
                            morePerson.getMens().add(men);
                        }


                    }
                });
                break;
            case 6://同步操作：增加一对多表，Person包含多个Men(以copyToRealm为例)
                final MorePerson morePerson1 = new MorePerson();
                morePerson1.setCity("杭州");
                morePerson1.setProject("开发工程师");
                morePerson1.setTime(simpleDateFormat.format(new Date()));
                RealmList<Men> menList = new RealmList<>();
                for (int i = 0; i < 3; i++) {
                    Men men2 = new Men();
                    men2.setName("huangxiaoguo" + i);
                    men2.setAge(new Random().nextInt(100));
                    menList.add(men2);
                }
                morePerson1.setMens(menList);
                for (int i = 0; i < 3; i++) {
                    Men men2 = new Men();
                    men2.setName("huangxiaoguo" + i);
                    men2.setAge(new Random().nextInt(100));
                    morePerson1.getMens().add(men2);
                }
                mRealm.executeTransaction(new Realm.Transaction() {
                    @Override
                    public void execute(Realm realm) {
                        realm.copyToRealm(morePerson1);
                    }
                });
                break;

            case 7://同步操作：beginTransaction和commitTransaction方法插入数据
                //注意：在UI和后台线程同时开启创建write的事务，可能会导致ANR错误。
                // 为了避免该问题，可以使用executeTransactionAsync来实现。
                mRealm.beginTransaction();//开启事务
                Student student1 = mRealm.createObject(Student.class);
                student1.setName("事务方式插入数据");
                student1.setNum(new Random().nextInt(100) + 100);
                mRealm.commitTransaction();
                break;

            case 8://异步操作：使用executeTransactionAsync直接插入数据
                //该方法会开启一个子线程来执行事务，并且在执行完成后进行结果通知。
                realmAsyncTask = mRealm.executeTransactionAsync(new Realm.Transaction() {
                    @Override
                    public void execute(Realm realm) {
                        Student student2 = realm.createObject(Student.class);
                        student2.setName("使用executeTransactionAsync直接插入数据");
                        student2.setNum(new Random().nextInt(100) + 200);
                    }
                });

                break;

            case 9://异步操作：使用executeTransactionAsync并且进行监听
                //注意：如果当Acitivity或Fragment被销毁时，在OnSuccess或OnError中执行UI操作，
                // 将导致程序奔溃 。用RealmAsyncTask .cancel();可以取消事务
                //在onStop或onDestroy中调用，避免crash
                realmAsyncTask = mRealm.executeTransactionAsync(new Realm.Transaction() {
                    @Override
                    public void execute(Realm realm) {
                        Student student2 = realm.createObject(Student.class);
                        student2.setName("使用executeTransactionAsync监听");
                        student2.setNum(new Random().nextInt(100) + 300);
                    }
                }, new Realm.Transaction.OnSuccess() {
                    @Override
                    public void onSuccess() {
                        UIUtils.showToast("添加成功");
                    }
                }, new Realm.Transaction.OnError() {
                    @Override
                    public void onError(Throwable error) {
                        UIUtils.showToast("添加失败");
                    }
                });
                break;
            case 10://将Json字符串转化为对象(使用Json字符串插入数据)
                mRealm.executeTransaction(new Realm.Transaction() {
                    @Override
                    public void execute(Realm realm) {
                        String stockJson = UIUtils.getJson("Stock");
                        try {
                            JSONObject js = new JSONObject(stockJson);
                            String result = js.optString("result");

                            JSONArray jsonArray = new JSONArray(result);
                            String resultOne = jsonArray.optString(0);

                            JSONObject js2 = new JSONObject(resultOne);
                            String data = js2.optString("data");
                            realm.createObjectFromJson(Stock.class, data);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }

                    }
                });
                break;
        }
    }
}
